home *** CD-ROM | disk | FTP | other *** search
- /* Terminal0.c
-
- Autor: E.G. Meyzis, Mai 1992
-
- Compile Instr. fuer DICE: execute cterm0
- dcc Terminal0.c -c -o t:Terminal0.o
-
- Link Instr. fuer DICE: execute lterm0
- dlink dlib:c.o t:Terminal0.o dlib:c.lib+
- dlib:amigas20.lib dlib:auto.lib dlib:x.o -o Terminal0
- */
-
- #include <Devices/Serial.h>
- #include <Dos/Dos.h>
- #include <Dos/DosExtens.h>
- #include <Exec/Exec.h>
- #include <Intuition/Intuition.h>
- #include <stdlib.h>
- #include <stdio.h>
-
- /* +++++++++ Definitionen ++++++++++++
- */
- #define TRUE 1 /* um mit dem Datentyp BOOL zu arbeiten */
- #define FALSE 0
-
- /* zwei Definitionen fuer DOS-Fenster */
-
- #define TxTitle "CON:0/0/500/100/ Terminal-Send "
- #define RxTitle "CON:0/101/500/100/ Terminal-Receive "
-
- /* Texte zur Info bei Text-Senden/Empfangen */
-
- #define Senden "\nSende Textdatei\n\n"
- #define Empfang "\nwarte auf Textdatei\n\n"
- #define Beendet "\nÜbertragung beendet\n\n"
-
- #define Unit0 0 /* eingebaute ser. Schnittstelle */
- #define PLaenge 512 /* Pufferlaenge Datemuebertrag. */
-
- struct GetBlock /* nur in GetWinPtr verwendet */
- {
- struct StandardPacket stdPkt;
- struct InfoData info;
- };
-
- /* +++++++++ Datentypen ++++++++++++
- */
- typedef char BOOL;
- typedef char *CharPtr;
- typedef struct IOExtSer *IOExtSerPtr;
- typedef struct FileHandle *FileHandleBPtr; /* BPTR */
- typedef struct FileHandle *FileHandlePtr; /* Adresse */
- typedef struct Window *WindowPtr;
- typedef struct GetBlock *GetBlockPtr;
- typedef struct MessagePort *MsgPortPtr;
- typedef struct IntuiMessage *IntuiMessagePtr;
-
-
- APTR GetSysBase(); /* Adr ExecBase aus Adresse 4 holen */
-
- void GetWinPointer (FileHandleBPtr *winHdl,
- WindowPtr *winPtr);
- void MakeWindow(CharPtr namePtr,
- WindowPtr *winPtr,
- FileHandleBPtr *fileHdl);
- BOOL WindowsAngelegt();
-
- void SetBaudRate(IOExtSerPtr serPtr);
- BOOL InitSerialDev(IOExtSerPtr serPtr, int cmnd);
- BOOL SerialVorbereitet();
- void SetTermChars(IOExtSerPtr serPtr);
- void FlushSerialDevice();
-
- void SendeTextDatei(IOExtSerPtr txReqPtr);
- void EmpfangeTextDatei(IOExtSerPtr rxReqPtr);
-
- void TerminalLoop();
- void Aufraeumen();
-
- /* +++++++++ globale Variablen ++++++++++++
- */
- struct ExecBase *execBasePtr;
-
- /*
- Doppelt ausgelegte Datenstrukturen
-
- Sendeteil: Empfangsteil:
- */
- /* Device zweimal oeffnen */
- struct IOExtSer txRequest, rxRequest;
-
- /* jedem Device seinen Puffer */
- char rxPuffer[PLaenge], txPuffer[PLaenge];
-
- /* getrennte Fenster fuer Ein-/Ausgaben */
- FileHandleBPtr txWin, rxWin;
- WindowPtr txWinPtr, rxWinPtr;
-
-
-
- APTR GetSysBase() /* Adr ExecBase aus Adresse 4 holen */
- {
- long *systemBasis;
-
- systemBasis = (APTR)4;
- return (APTR)*systemBasis;
- }
-
-
- /* Mit Dos.Open geoeffnete Fenster liefern nur einen Handle
- und leider nicht den WindowPtr; deshalb:
- */
- void GetWinPointer (FileHandleBPtr *winHdl,
- WindowPtr *winPtr)
- {
- MsgPortPtr portPtr;
- GetBlockPtr pktPtr;
-
- FileHandlePtr wHdlPtr;
-
- *winPtr = NULL; /* negatives Vorurteil */
- if (IsInteractive(*winHdl)) /* Fenster vorhanden? */
- {
- wHdlPtr = (APTR)((long)*winHdl) << 2; /* BPTR -> Adr */
- if (portPtr = (MsgPortPtr)CreateMsgPort())
- {
- /* Speicher fuer Dos.Packet anfordern*/
-
- pktPtr=(GetBlockPtr)AllocMem(sizeof(struct GetBlock),
- MEMF_CLEAR|MEMF_PUBLIC);
- if (pktPtr) /* Dos.Packet initialisieren */
- {
- pktPtr->stdPkt.sp_Pkt.dp_Link =
- &pktPtr->stdPkt.sp_Msg;
- pktPtr->stdPkt.sp_Pkt.dp_Port = portPtr;
- pktPtr->stdPkt.sp_Pkt.dp_Type = ACTION_DISK_INFO;
- pktPtr->stdPkt.sp_Pkt.dp_Arg1 = &pktPtr->info >>2;
- pktPtr->stdPkt.sp_Msg.mn_Node.ln_Name =
- &pktPtr->stdPkt.sp_Pkt;
- pktPtr->stdPkt.sp_Msg.mn_Node.ln_Type= NT_MESSAGE;
- pktPtr->stdPkt.sp_Msg.mn_Length =
- sizeof(struct Message);
-
- PutMsg(wHdlPtr->fh_Type, pktPtr);/*und absenden */
- do
- WaitPort(portPtr); /* auf Antwort von Dos */
- while (APTR)GetMsg(portPtr) != pktPtr;
-
- if (pktPtr->stdPkt.sp_Pkt.dp_Res1)/* Antwort ok */
- *winPtr = (APTR)pktPtr->info.id_VolumeNode;
-
- DeleteMsgPort(portPtr);
- FreeMem(pktPtr, sizeof(struct GetBlock));
- }
- else
- DeleteMsgPort(portPtr);
- }
-
- } /* Interactive */
- }
-
-
- /* Dos.Fenster anlegen und WindowPtr holen */
-
- void MakeWindow(CharPtr namePtr,
- WindowPtr *winPtr,
- FileHandleBPtr *fileHdl)
-
- {
- *fileHdl = (FileHandleBPtr)Open(namePtr, MODE_NEWFILE);
- if (*fileHdl)
- GetWinPointer(&(*fileHdl), &(*winPtr));
- }
-
-
- /* Beide Terminal-Fenster anlegen und bei Fehlschlag
- Ressourcen freigeben.
- */
- BOOL WindowsAngelegt()
- {
- BOOL angelegt;
-
- angelegt = FALSE; /* zunaechst keines vorhanden */
-
- MakeWindow(TxTitle, &txWinPtr, &txWin);/* Sende-Fenster */
- if (txWinPtr)
- {
- angelegt = TRUE;
-
- /* um Tastatureingaben durch Intuition abzufangen */
-
- ModifyIDCMP(txWinPtr, IDCMP_RAWKEY|IDCMP_VANILLAKEY);
-
- MakeWindow(RxTitle, &rxWinPtr, &rxWin);/*Empf.-Fenst */
- if (rxWinPtr = NULL)
- {
- angelegt = FALSE; /* Sendefenster aufgeben */
- Close(txWin);
- txWin = NULL;
- }
- }
- else /* WindowPtr nicht zu ermitteln */
- if (txWin)
- Close(txWin); /* deshalb schliessen */
- return angelegt;
- }
-
- /* 3. Erweiterung Listing 3-3 hier einsetzen */
-
- /* 4. Erweiterung Listing 3-4 hier einbauen */
-
-
- /* Device-Struktur initialisieren und Device oeffnen */
-
- BOOL InitSerialDev(IOExtSerPtr serPtr, int cmnd)
- {
- MsgPortPtr portPtr;
- BOOL erfolg;
-
- erfolg = FALSE;
- portPtr = (MsgPortPtr)CreateMsgPort(); /* fuer Device */
- if (portPtr)
- {
- serPtr->io_SerFlags = SERF_SHARED; /* Mehrfachutzung */
- serPtr->IOSer.io_Length = 1;/* 1 Byte lesen/schreib. */
- serPtr->IOSer.io_Message.mn_ReplyPort = portPtr;
-
- OpenDevice(SERIALNAME, Unit0, serPtr, 0);
- if (serPtr->IOSer.io_Error != IOERR_OPENFAIL)
- {
- erfolg = TRUE;
-
- /* 3. Erweiterung Listing 3-3 hier aufrufen
- SetBaudRate(serPtr);
- */
- serPtr->IOSer.io_Command = cmnd;/* CMD_WRITE/READ */
- }
- else /* Device nicht zu oeffnen */
- {
- DeleteMsgPort
- (serPtr->IOSer.io_Message.mn_ReplyPort);
- serPtr->IOSer.io_Message.mn_ReplyPort = NULL;
- }
- }
- return erfolg;
- }
-
-
- BOOL SerialVorbereitet() /* getrennte Devices als Sende- */
- { /* Empfangskanal oeffnen */
- BOOL vorbereitet;
-
- if (InitSerialDev(&txRequest, CMD_WRITE)) /* Sendekanal */
- {
- vorbereitet = TRUE;
- txRequest.IOSer.io_Data=txPuffer;/*f. Dateiuebertrag.*/
-
- if (InitSerialDev(&rxRequest, CMD_READ))/*Empf.-Kanal*/
- {
- rxRequest.IOSer.io_Data = rxPuffer; /* ext. Puffer*/
- }
- else /* kein Empfangskanal zu oeffnen */
- {
- vorbereitet = FALSE;
- DeleteMsgPort
- (txRequest.IOSer.io_Message.mn_ReplyPort);
- txRequest.IOSer.io_Message.mn_ReplyPort = NULL;
- }
- }
- else/*kein Kanal zu oeffnen; Device evtl exklusiv belegt*/
- vorbereitet = FALSE;
-
- return vorbereitet;
- }
-
-
- /* 5. Erweiterung Listing 3-5 hier einbauen */
-
- /* 6. Erweiterung Listing 3-6 hier einbauen */
-
- /* 6. Erweiterung Listing 3-6 */
-
-
- void TerminalLoop() /* Hauptschleife des Prog. */
- {
- IntuiMessagePtr inMsgPtr; /* fuer IDCMP-Nachr. aus dem */
- long klasse, /* Sendefenster */
- done,
- txSig, /*aus UserPort des Sendefensters */
- rxSig, /* aus Empfangs-Device-Struktur */
- erwartSig, /* Kombination txSig | rxSig */
- erhaltSig; /* angekommene Signale */
- int raw; /* fuer Tastatur-Codes */
-
- txSig = 1 << txWinPtr->UserPort->mp_SigBit;
- rxSig = 1 <<
- rxRequest.IOSer.io_Message.mn_ReplyPort->mp_SigBit;
- erwartSig = txSig | rxSig;
-
- SendIO(&(rxRequest)); /* async. aufs 1. Zeichen warten */
- for(;;)
- {
- erhaltSig = Wait(erwartSig); /* Tastendruck/Empfang */
- if (txSig & erhaltSig) /*Taste im Sendefenster gedr. */
- {
- inMsgPtr = (IntuiMessagePtr) /* Msg. abholen */
- GetMsg(txWinPtr->UserPort);
-
- klasse = inMsgPtr->Class; /* copy Msg teilweise */
- raw = inMsgPtr->Code;
-
- ReplyMsg(inMsgPtr); /* Msg beantworten */
-
- if (IDCMP_VANILLAKEY & klasse) /* ASCII-Zeichen */
- {
- txPuffer[0] = raw; /* Zeichen in Sende-Puffer */
- if (txPuffer[0] != 033) /* nicht ESC gedrueckt */
- {
- done = Write(txWin, txPuffer, 1); /* Echo */
- DoIO(&txRequest); /* Zeichen senden */
- }
- else /* ESC gedrueckt */
- break; /* Programm abbrechen */
- }
- else
- if (IDCMP_RAWKEY & klasse) /* z.B. F1 - F10 gedr.*/
- {
- if ((raw >= 80) && (raw <= 89))
- {
- /* Funktionstasten auswerten F1 - F10 */
- if (raw == 80)
- { /* F1 */
- /* 5. Erweiterung
- Aufruf SendeTextDatei(txRequest);
- aus Listing 3-5 hier einfuegen
- */
- }
- else
- if (raw == 81) /* F2 */
- {
- /* 6. Erweiterung
- Aufruf EmpfangeTextDatei(rxRequest);
- aus Listing 3-6 hier einfuegen
- */
- }
- } /* raw >= 80*/
- } /* IDCMP_RAWKEY */
- } /* txSig */
- if (rxSig & erhaltSig)/* mind. 1 Zeich. im Empf-kanal*/
- {
- WaitIO(&rxRequest); /* dieses abholen */
- if (rxRequest.IOSer.io_Error == 0)
- done = Write(rxWin, rxPuffer, 1);/*u. ausgeben */
-
- /* 2. Erweiterung gem Listing 3-2 hier einfuegen */
-
- SendIO(&rxRequest); /* aufs naechste Zeich. wart. */
- }
- } /* for */
- AbortIO(&rxRequest); /* Auftrag an Device abbrechen */
- WaitIO(&rxRequest);
- }
-
- /* 1. Erweiterung FlushSerialDevice;
- Listing 3-1 hier einbauen
- */
-
- void Aufraeumen()
- {
- DeleteMsgPort(rxRequest.IOSer.io_Message.mn_ReplyPort);
- CloseDevice(&rxRequest);
- DeleteMsgPort(txRequest.IOSer.io_Message.mn_ReplyPort);
- CloseDevice(&txRequest);
- Close(rxWin);
- Close(txWin);
- /* 1. Erweiterung
- Aufruf FlushSerialDevice aus
- Listing 3-1 hier vornehmen
- */
- }
-
- int main()
- {
- BOOL done;
-
- execBasePtr = GetSysBase(); /* Adr ExecBase beschaffen */
-
- if (execBasePtr->LibNode.lib_Version >= 36) /* ja, OS 2 */
- {
- if (WindowsAngelegt() && SerialVorbereitet())
- {
- TerminalLoop(); /* Steuerschleife des Programms */
- Aufraeumen();
- }
- }
- return 0;
- }
-